如果火锅只能吃三样......
微信公众号:zuobangbang
昨天刷过微博的筒子们应该都看到了这样一条热搜:如果火锅只能点三样,话说我能都要吗
在大家心中的TOP3是谁呢???
今天要爬的是图院长发的一条微博,截至上午9:14,一共有4.6万条评论。微博作为反爬界的大佬,是不会要你轻易爬取到它的信息的。(曾经尝试过用微博API,但是密钥的申请过于复杂,直接放弃了)网页不好爬,那我们就爬手机端啊。Fiddler的下载安装请参考用Fiddler+MongoDB抓取猫眼APP短评。
微博评论采用的是异步加载的方式,不停往下翻页,在Fiddler不断的有数据加载进来;
这个页面的URL非常的复杂(https://api.weibo.cn/2/comments/build_comments?flow=0&gsid=_2A2528V-DDeRxGeRM7loV9ifJyDuIHXVTp9RLrDV6PUJbkdAKLVf5kWpNU807bwxYkTUD9lwoQyaK4ajn_4FoWbka&wm=3333_2001&i=2a48abc&b=0&from=108B193010&c=iphone&networktype=wifi&v_p=69&skin=default&v_f=1&s=b1c8ec8f&lang=zh_CN&sflag=1&ua=iPhone9,1__weibo__8.11.1__iphone__os11.2.5&ft=11&aid=01AkR6c52cGZnAKXiIy1qC93kKA4LStXUv_uVymvDYrbPVZaw.&is_append_blogs=1&mid=4308928831894875&fid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D3&uicode=10000002&count=20&trim_level=1&moduleID=feed&max_id=141992686212489&is_show_bulletin=2&fetch_level=0&_status_id=4308928831894875&max_id_type=0&id=4308928831894875&luicode=10000003&featurecode=10000085&is_mix=1&page=0&lfid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D3&lcardid=seqid%3A23443762%7Ctype%3A1%7Ct%3A31%7Cpos%3A1-2-0%7Cq%3A%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%7Cext%3A%26cate%3D306%26mid%3D4308928831894875%26qtime%3D1542854023%26&rid=0_0_0_2667276034987506065_0_0&cum=DF372ED1)。对比了两页评论URL的参数,发现它的page均为0,只有下面这几个参数是不同的。
在这个URL返回的JSON里,笔者发现了这个:在URL和JSON里,都出现了max_id。前一面JSON出现的max_id在下一面的URL里。
因此有了一个大胆的猜想,参数(max_id)就是充当了一个翻页的作用,第一面的max_id会出现在第二面的URL里。
整个程序确实跑起来了,但是它会不定时的返回一个取值为0 的max_id;程序就会自动结束。所以,我加入了一个控制次数的变量zero=5;max_id取0在五次内,程序都不会结束。
while zero:
url ='https://api.weibo.cn/2/comments/build_comments?flow=1&gsid=_2A2528V-DDeRxGeRM7loV9ifJyDuIHXVTp9RLrDV6PUJbkdAKLVf5kWpNU807bwxYkTUD9lwoQyaK4ajn_4FoWbka&wm=3333_2001&i=2a48abc&b=0&from=108B193010&c=iphone&networktype=wifi&v_p=69&skin=default&v_f=1&s=b1c8ec8f&lang=zh_CN&sflag=1&ua=iPhone9,1__weibo__8.11.1__iphone__os11.2.5&ft=11&aid=01AkR6c52cGZnAKXiIy1qC93kKA4LStXUv_uVymvDYrbPVZaw.&is_append_blogs=1&mid=4308928831894875&fid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&uicode=10000002&count=20&trim_level=1&moduleID=feed&max_id={}&is_show_bulletin=2&fetch_level=0&_status_id=4308928831894875&max_id_type=0&id=4308928831894875&luicode=10000003&featurecode=10000085&is_mix=1&page=0&lfid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&lcardid=seqid%3A870460522%7Ctype%3A1%7Ct%3A1%7Cpos%3A1-2-0%7Cq%3A%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%7Cext%3A%26cate%3D306%26mid%3D4308928831894875%26qtime%3D1542865414%26&rid=0_0_0_2669675512959047934_0_0&cum=6DD80FF3'.format(max_id)
try:
max_id,num=get_inf(url)
except Exception as e:
print(e)
time.sleep(30)
max_id,num=get_inf(url)
if not max_id:
zero=zero-1
time.sleep(60)
程序跑起来后发现,下面这段程序出了一个很大的逻辑问题。当max_id为0时,在开始下一次循环时,max_id仍为0,会让程序自动从当前时间点的最新评论开始爬。这段程序我是昨天下午快三点跑的,仔细看下图会看到当max_id为0,它的下一次循环时间从14:37回到了14:51,这意味着整段程序一直在对那几千条评论重复抓取。
所以我在上面那段程序的基础上加入了一个变量max,在max_id更新前将它先保存下来,如果max_id变为0,把max的值赋予给max_id。
while zero:
url ='https://api.weibo.cn/2/comments/build_comments?flow=1&gsid=_2A2528V-DDeRxGeRM7loV9ifJyDuIHXVTp9RLrDV6PUJbkdAKLVf5kWpNU807bwxYkTUD9lwoQyaK4ajn_4FoWbka&wm=3333_2001&i=2a48abc&b=0&from=108B193010&c=iphone&networktype=wifi&v_p=69&skin=default&v_f=1&s=b1c8ec8f&lang=zh_CN&sflag=1&ua=iPhone9,1__weibo__8.11.1__iphone__os11.2.5&ft=11&aid=01AkR6c52cGZnAKXiIy1qC93kKA4LStXUv_uVymvDYrbPVZaw.&is_append_blogs=1&mid=4308928831894875&fid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&uicode=10000002&count=20&trim_level=1&moduleID=feed&max_id={}&is_show_bulletin=2&fetch_level=0&_status_id=4308928831894875&max_id_type=0&id=4308928831894875&luicode=10000003&featurecode=10000085&is_mix=1&page=0&lfid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&lcardid=seqid%3A870460522%7Ctype%3A1%7Ct%3A1%7Cpos%3A1-2-0%7Cq%3A%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%7Cext%3A%26cate%3D306%26mid%3D4308928831894875%26qtime%3D1542865414%26&rid=0_0_0_2669675512959047934_0_0&cum=6DD80FF3'.format(max_id)
max = max_id
try:
max_id,num=get_inf(url)
except Exception as e:
print(e)
time.sleep(30)
max_id,num=get_inf(url)
if not max_id:
max_id=max
zero=zero-1
time.sleep(60)
加入这样一个变量后,整段程序变得正常起来,从下图可以看到,当max_id变为0时,时间从13:35:35变成了13:35:10。
这段代码是昨天下午三点多跑的,一共爬了差不多两万条评论。但是这个话题太火了,一直在热搜榜上,所以今早重新爬了一次,一共爬了41897条评论。
整个爬虫代码如下:
import random
from pymongo import MongoClient
import requests
import time
collection=MongoClient('localhost',27017)
collection=collection['weibo']['weibo']
user=['Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36']
headers={
'Host': 'api.weibo.cn',
'User-Agent':random.choice(user),
'Cookie':'ALF=1544929289; _T_WM=39e20928a39c3b92a9cdd8d71f3e2550; WEIBOCN_FROM=1110006030',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'}
def get_inf(url):
html = requests.get(url, headers=headers).json()
max_id = html['max_id']
print(max_id)
n=0
print( html['root_comments'])
for i in html['root_comments']:
inf = {}
inf['text'] = i['text']
inf['time'] = i['created_at']
inf['disable_reply'] = i['disable_reply']
inf['liked']=i['like_counts']
inf['nick'] = i['user']['name']
#inf['class'] = i['user']['class']
inf['sex'] = i['user']['gender']
inf['city'] = i['user']['city']
inf['pro'] = i['user']['province']
inf['location'] = i['user']['location']
inf['关注'] = i['user']['friends_count']
inf['fans'] = i['user']['followers_count']
n=n+1
collection.insert_one(inf)
#print(inf)
return max_id,n
total=0
max_id='0'
zero=15
while zero:
url ='https://api.weibo.cn/2/comments/build_comments?flow=1&gsid=_2A2528V-DDeRxGeRM7loV9ifJyDuIHXVTp9RLrDV6PUJbkdAKLVf5kWpNU807bwxYkTUD9lwoQyaK4ajn_4FoWbka&wm=3333_2001&i=2a48abc&b=0&from=108B193010&c=iphone&networktype=wifi&v_p=69&skin=default&v_f=1&s=b1c8ec8f&lang=zh_CN&sflag=1&ua=iPhone9,1__weibo__8.11.1__iphone__os11.2.5&ft=11&aid=01AkR6c52cGZnAKXiIy1qC93kKA4LStXUv_uVymvDYrbPVZaw.&is_append_blogs=1&mid=4308928831894875&fid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&uicode=10000002&count=20&trim_level=1&moduleID=feed&max_id={}&is_show_bulletin=2&fetch_level=0&_status_id=4308928831894875&max_id_type=0&id=4308928831894875&luicode=10000003&featurecode=10000085&is_mix=1&page=0&lfid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&lcardid=seqid%3A870460522%7Ctype%3A1%7Ct%3A1%7Cpos%3A1-2-0%7Cq%3A%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%7Cext%3A%26cate%3D306%26mid%3D4308928831894875%26qtime%3D1542865414%26&rid=0_0_0_2669675512959047934_0_0&cum=6DD80FF3'.format(max_id)
max = max_id
try:
max_id,num=get_inf(url)
except Exception as e:
print(e)
time.sleep(30)
max_id,num=get_inf(url)
if not max_id:
max_id=max
zero=zero-1
time.sleep(60)
total=total+num
time.sleep(random.randint(1,2))
print(total)
有了数据我们就可以进行分析咯。。。
先来看看评论的男女比;评论的女生比男生多了不止一点点,完全不在一个量级上。女生差不多是男生的六倍!
下面来看看各时间段发表的评论数,昨天早上笔者醒来时刷了刷微博,大概早上九点,这条微博还在实时上升热点一栏;等笔者起来时大约10点半,这条微博已经冲进了热搜榜的前二十;等到下午三点左右,差不多在三十名;晚上大约十点半到宿舍,刷微博发现这个热搜仍然在三十名左右;这个排名的变化和下图是基本吻合的,所以大家不要老是说买热搜啦
有点好奇点赞数最多的是哪几条评论耶~下面这十一条是点赞数超过1000的评论,大家一起来品一品吧~
肉片拼盘,蔬菜拼盘,丸子拼盘 96985
毛肚 虾滑 肥牛[笑cry] 20752
肥牛土豆虾滑 8356
肥牛肥牛肥牛 6655
我自己给钱,火锅没有妥协[挖鼻] 6452
小孩子才选三个菜 大人要选三个拼盘!!!![doge] 6171
没有爱鸭肠脑花的么[泪] 4063
虾滑 肥牛 牛肚 2145
香菜 涮羊肉 牛百叶 1306
嫩牛肉、黄喉和虾滑[作揖] 1248
香菇、金针菇、鸡腿菇 1075
哈哈哈,第一条实在是太有才了,必须给个大大的赞👍。你说只让选三样,那我就选三个拼盘。下面来看看TOP3!
图左是单纯统计评论里各个单词出现的次数,图右将点赞数加进入,比如点赞数第一的评论:肉片拼盘,蔬菜拼盘和丸子拼盘,点赞数为96985,根据图左的算法,则算肉片拼盘,蔬菜拼盘和丸子拼盘出现一次,根据图右的算法,肉片拼盘,蔬菜拼盘和丸子拼盘出现次数为96985+1。图左的TOP3分别是肥牛,虾滑,毛肚;图右的TOP3分别是拼盘,蔬菜拼盘和丸子拼盘。广大网友真的非常机智噢~~~
上图是各省的评论数,四川果然是第一名,其次是江苏,北京,广东和山东。四川火锅不是吹的啊,全民火锅的节奏。来看看四川人最喜欢吃的TOP15吧。
土豆居然冲进了前三,虾滑变成了第四名。而毛肚变成了第一名,原来四川人最爱吃的是毛肚啊;如果给四川人点菜,一定记得点毛肚噢。
大家猜对TOP3了吗~~~
全部代码后续会上传到GitHub:https://github.com/zuobangbang/huoguo
Python爱好者社区历史文章大合集:
Python爱好者社区历史文章列表(每周append更新一次)
关注后在公众号内回复“课程”即可获取:
小编的转行入职数据科学(数据分析挖掘/机器学习方向)【最新免费】
小编的Python入门免费视频课程!!!
小编的Python快速上手matplotlib可视化库!!!
崔老师爬虫实战案例免费学习视频。
陈老师数据分析报告制作免费学习视频。
玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。